Appearance
Toast 訊息實現
說明
Toast 訊息(或稱吐司訊息)是一種非侵入式的通知提示,它會在短暫顯示後自動消失,不會中斷使用者的操作流程。 在 Avalonia 中實作此功能非常直觀,我們只需借助社群套件即可快速完成。實作流程主要分為以下五個步驟:
- 安裝 NuGet 套件:引入
Notification.Avalonia函式庫。 - 註冊樣式資源:在
App.axaml中引入通知視窗的主題樣式。 - 掛載通知管理器:在
MainWindow(View 層) 初始化通知顯示的宿主區域。 - 封裝通知服務:建立
NotificationService(與介面),以便透過依賴注入 (DI) 使用。 - ViewModel 整合:在 ViewModel 中注入服務,並透過
RelayCommand觸發通知測試。
安裝 NuGet 套件
搜尋Notification.Avalonia 後安裝即可,本文撰寫時版本為2.2.0
註冊樣式資源
編輯App.axaml,加入套件樣式
xml
<Application.Styles>
<FluentTheme />
<StyleInclude Source="avares://Notification.Avalonia/Themes/Generic.xaml" />
</Application.Styles>
掛載通知管理器
C#
using System;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using AvaloniaSideBarEx.Services;
using Microsoft.Extensions.DependencyInjection;
namespace AvaloniaSideBarEx.Views;
public partial class MainWindow : Window
{
private WindowNotificationManager? _manager;
public MainWindow()
{
InitializeComponent();
this.Opened += MainWindow_Opened;
}
private void MainWindow_Opened(object? sender, EventArgs e)
{
// 1. 取得視窗的頂層容器
var topLevel = TopLevel.GetTopLevel(this);
if (topLevel != null)
{
// 2. 建立通知管理器
_manager = new WindowNotificationManager(topLevel)
{ Position = NotificationPosition.TopRight,
MaxItems = 3
};
// A. 從 App 取得 DI 容器
var app = (App)Application.Current!;
// B. 從容器中取出 NotificationService
var service = app.Services?.GetRequiredService<INotificationService>();
// C. 進行「配對」
// (我們需要轉型成 NotificationService 才能設定 Manager 屬性)
if (service is NotificationService concreteService)
{
concreteService.Manager = _manager;
}
}
}
}
封裝通知服務
C#
INotificationService.cs
namespace AvaloniaSideBarEx.Services;
public interface INotificationService
{
void Show(string title, string message, string type = "Info");
}
C#
NotificationService.cs
using Avalonia.Controls.Notifications;
namespace AvaloniaSideBarEx.Services;
public class NotificationService: INotificationService
{
public WindowNotificationManager? Manager { get; set; }
public void Show(string title, string message, string type = "Info")
{
if (Manager is null) return;
var notificationType = type switch
{
"Success" => NotificationType.Success,
"Error" => NotificationType.Error,
"Warning" => NotificationType.Warning,
_ => NotificationType.Information
};
Manager.Show(new Notification(title, message, notificationType));
}
}
C#
App.axaml.cs
...略
public override void OnFrameworkInitializationCompleted()
{
// 初始化 DI 容器
var collection = new ServiceCollection();
// 註冊 Service
collection.AddSingleton<INotificationService, NotificationService>();
...略
ViewModel 整合
C#
HomeViewModel.cs
using AvaloniaSideBarEx.Services;
using CommunityToolkit.Mvvm.Input;
namespace AvaloniaSideBarEx.ViewModels;
public partial class HomeViewModel(INotificationService notificationService): ViewModelBase
{
public string WelcomeMessage => "Home頁面";
[RelayCommand]
public void NotificationTest()
{
notificationService.Show("成功", "Toast 訊息測試!", "Success");
}
}
xml
HomeView.axml
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:AvaloniaSideBarEx.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:DataType="vm:HomeViewModel"
x:Class="AvaloniaSideBarEx.Views.HomeView">
<StackPanel Margin="20" Spacing="15">
<TextBlock Text="{Binding WelcomeMessage}" FontSize="16" Foreground="#34495e"/>
<Button Command="{Binding NotificationTest}">Toast</Button>
</StackPanel>
</UserControl>